﻿/*-----------------------------------------------
// File: EnginePlayerAI.cs
// Description: 
// Author: Shaobing	492057342@qq.com
-----------------------------------------------*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Battle.Engine.LogicModel;

namespace Battle.Engine.AI
{
    public class EnginePlayerAI : EngineAI
    {
        protected EngineAIMsg curUltiMsg = null;
        protected EnginePlayerAIMsg curAiMsg = null;
        protected Queue<EnginePlayerAIMsg> aiMsgQueue = new Queue<EnginePlayerAIMsg>();
        protected List<FSkill> dealingSkills = new List<FSkill>();

        protected bool isUltimating = false;

        public override void Run()
        {
            if (isRunning == true)
                return;
            isRunning = true;

            base.Run();
            aiMsgQueue.Clear();
            dealingSkills.Clear();
            curAiMsg = null;
            curUltiMsg = null;
            List<FActor> runActors = GetNormalSkillCastOrderActors();
            foreach (var actor in runActors)
            {
                if (actor.state == FActorState.DEAD || actor.state == FActorState.WAEKDEAD)
                    continue;
                EnginePlayerAIMsg aiMsg = new EnginePlayerAIMsg(actor);
                var skill1 = actor.GetFSkill((int)SkillType.Skill1);
                if (skill1 != null && actor.isCanDoSkill(skill1))
                {
                    aiMsg.AddSkill(skill1);
                }
                var skill2 = actor.GetFSkill((int)SkillType.Skill2);
                if (skill2 != null && actor.isCanDoSkill(skill2))
                {
                    aiMsg.AddSkill(skill2);
                }
                if (aiMsg.skills.Count > 0)
                {
                    aiMsgQueue.Enqueue(aiMsg);
                }
            }
            curAiMsgDeltaTime = 0f;
            isUltimating = false;
        }

        double curAiMsgDeltaTime;

        public double PlayerAIDeltaTime()
        {
            return engine.data.tableDataUtil.GetPlayerAIDeltaTime();
        }

        public override void Update(double deltaTime)
        {
            if (isRunning == false)
                return;

            for (int i = 0; i < dealingSkills.Count; ++i)
            {
                if (dealingSkills[i].state == FSkillState.FINISH)
                {
                    dealingSkills.RemoveAt(i);
                    i--;
                }
            }

            if (isUltimating)
            {
                var skill = curUltiMsg.skill;
                if (skill.state == FSkillState.FINISH && dealingSkills.Count == 0)
                {
                    isUltimating = false;
                    curAiMsgDeltaTime = 0;
                    curUltiMsg = null;
                    return;
                }
            }
            else {
                if (curUltiMsg == null)
                {
                    if (curUltiMsg == null)
                    {
                        var ultiActors = GetUltimateReadyActor();
                        if (ultiActors.Count > 0)
                        {
                            curUltiMsg = new EngineAIMsg(ultiActors[0], (int)SkillType.Ultimate);
                        }
                    }
                }
                if (curUltiMsg != null)
                {
                    var skill = curUltiMsg.skill;
                    engine.DoSkill(skill.actor.player.camp, skill.actor.uniqueId, skill.index);
                    Debug.Log("[Debug] Actor " + skill.actor.uniqueId + " DoUltimate.");
                    isUltimating = true;
                    return;
                }



                if (curAiMsgDeltaTime > 0)
                {
                    curAiMsgDeltaTime -= deltaTime;
                    return;
                }
                if (aiMsgQueue.Count > 0)
                {
                    var aiMsg = aiMsgQueue.Dequeue();
                    while (aiMsg.skills.Count > 0)
                    {
                        var skill = aiMsg.skills.Dequeue();
                        engine.DoSkill(skill.actor.player.camp, skill.actor.uniqueId, skill.index);
                        dealingSkills.Add(skill);
                    }
                    curAiMsgDeltaTime = PlayerAIDeltaTime();
                }
            }

            if (aiMsgQueue.Count == 0 && dealingSkills.Count == 0 && curUltiMsg == null && !isUltimating && GetUltimateReadyActor().Count == 0 && IsActorsHaveSkillInQueue())
            {
                if (data.compute.IsSkipping())
                {
                    if (callback != null)
                        callback.FinishRound();
                }
                else {
                    if (callback != null)
                        callback.HaventActiveNormalSkill();
                }
            }

        }

        protected bool IsActorsHaveSkillInQueue() {
            foreach (var actor in player.actors) {
                if (actor.state == FActorState.DEAD || actor.state == FActorState.WAEKDEAD)
                    continue;
                if (actor.doSkill != null || actor.doUltimateSkill != null || actor.waitSkills.Count > 0) {
                    return false;
                }
            }
            return true;
        }


        protected List<FActor> GetNormalSkillCastOrderActors()
        {
            List<FActor> runActors = new List<FActor>();
            foreach (var actor in player.actors)
            {
                if (actor.state == FActorState.DEAD || actor.state == FActorState.WAEKDEAD)
                    continue;
                var skill1 = actor.GetFSkill(0);
                var skill2 = actor.GetFSkill(1);
                if ((skill1 != null && actor.isCanDoSkill(skill1)) || (skill2 != null && actor.isCanDoSkill(skill2)))
                {
                    runActors.Add(actor);
                }
            }
            runActors.Sort(delegate (FActor x, FActor y) {
                return x.MainPosition.ToFPID().CompareTo(y.MainPosition.ToFPID());
            });
            return runActors;
        }

    }

}